package uk.ac.jisc.depositmo.widgets;

/**
 * Copyright (c) 2011, University of Southampton
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * # Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer.
 * # Redistributions in binary form must reproduce the above copyright notice, 
 *     this list of conditions and the following disclaimer in the documentation 
 *     and/or other materials provided with the distribution.
 * # Neither the name of the University of Southampton nor the names of its
 *     contributors may be used to endorse or promote products derived from this
 *     software without specific prior written permission.
 *  
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import java.io.File;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

/**
 * 
 * @author Mark Borkum <mark.borkum@gmail.com>
 *
 */
public abstract class FileTransferImage extends Canvas {
	private static final String 
		MOUSE_OUT_IMAGE_FILENAME = "FileTransferImage_mouseout.png",
		MOUSE_OVER_IMAGE_FILENAME = "FileTransferImage_mouseover.png";
	
	public FileTransferImage(Composite parent) {
		super(parent, SWT.NONE);
		
		addListener(SWT.MouseDoubleClick, new Listener() {
			public void handleEvent(Event e) {
				final FileDialog fileDialog = new FileDialog(getShell());
				
				File[] response = fileDialog.open();
				
				if (response.length > 0) {
					filesDropped(response);
				}
			}
		});
		
		final ImageLoader imageLoader = new ImageLoader();
		
		final Image mouseOutImage, mouseOverImage;
		
		if (true) {
			final ImageData[] imageDataArray = imageLoader.load(getClass().getResourceAsStream(MOUSE_OUT_IMAGE_FILENAME));
			
			if (imageDataArray == null || imageDataArray.length == 0) {
				throw new RuntimeException("Failed to load image: '" + MOUSE_OUT_IMAGE_FILENAME + "'");
			} else {
				mouseOutImage = new Image(getDisplay(), imageDataArray[0]);
			}
		}
		
		if (true) {
			final ImageData[] imageDataArray = imageLoader.load(getClass().getResourceAsStream(MOUSE_OVER_IMAGE_FILENAME));
			
			if (imageDataArray == null || imageDataArray.length == 0) {
				throw new RuntimeException("Failed to load image: '" + MOUSE_OVER_IMAGE_FILENAME + "'");
			} else {
				mouseOverImage = new Image(getDisplay(), imageDataArray[0]);
			}
		}
		
		this.setBackgroundImage(mouseOutImage);
		this.setSize(mouseOutImage.getImageData().width, mouseOutImage.getImageData().height);
		this.setToolTipText("Drop file(s) here, or double-click to select files.");
		
		final DropTarget dropTarget = new DropTarget(this, DND.DROP_DEFAULT | DND.DROP_MOVE);
		
		final FileTransfer fileTransfer = FileTransfer.getInstance();
		
		dropTarget.setTransfer(new Transfer[] { fileTransfer });
		
		dropTarget.addDropListener(new DropTargetAdapter() {
			public void dragLeave(DropTargetEvent e) {
				setBackgroundImage(mouseOutImage);
				redraw();
			}
			
			public void dragOver(DropTargetEvent e) {
				setBackgroundImage(mouseOverImage);
				redraw();
			}
			
			public void drop(DropTargetEvent e) {
				if (fileTransfer.isSupportedType(e.currentDataType)) {
					String[] absolutePaths = (String[]) e.data;
					
					File[] files = new File[absolutePaths.length];
					
					for (int i = 0; i < absolutePaths.length; i++) {
						files[i] = new File(absolutePaths[i]);
					}
					
					filesDropped(files);
				}
			}
			
			public void dropAccept(DropTargetEvent e) {
				dragLeave(e);
			}
		});
	}
	
	public abstract void filesDropped(File[] files);
}
